package com.hollycrm.unicom.sheet.flowsupport.hibernate;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import net.sf.hibernate.type.Type;

import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate.HibernateCallback;
import org.springframework.orm.hibernate.HibernateTemplate;
import org.springframework.orm.hibernate.support.HibernateDaoSupport;

import com.hollycrm.unicom.security.AuthToken;
import com.hollycrm.unicom.sheet.Constants;
import com.hollycrm.unicom.sheet.business.hibernate.TimeLimit;
import com.hollycrm.unicom.sheet.flow.SheetAction;
import com.hollycrm.unicom.sheet.flow.SheetMove;
import com.hollycrm.unicom.sheet.flow.SheetOperation;
import com.hollycrm.unicom.sheet.flow.SheetProcess;
import com.hollycrm.unicom.sheet.flowsupport.DoOperateContext;
import com.hollycrm.unicom.sheet.flowsupport.FlowSupportManager;
import com.hollycrm.unicom.usersupport.Department;
import com.hollycrm.unicom.usersupport.DepartmentTreeViewObject;
import com.hollycrm.unicom.usersupport.hibernate.HibernateUserSupportHelper;

/**
 * HibernateFlowSupportManager
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author Tian Kai
 * @version 1.0
 */
public class HibernateFlowSupportManager
    extends HibernateDaoSupport
    implements FlowSupportManager {

    public HibernateFlowSupportManager() {
    }

    /**
     * getDeptAcceptCategoryList
     *
     * @param flowID String
     * @param deptID String
     * @param operateType String
     * @return List
     */
    public List getDeptAcceptCategoryList(String flowID, String deptID,
                                          String operateType) {
        throw new UnsupportedOperationException("not implement this method, use CodeManager.");
    }

    /**
     * getDeptReceiveCategoryList
     *
     * @param flowID String
     * @param deptID String
     * @param operateType String
     * @return List
     */
    public List getDeptReceiveCategoryList(String flowID, String deptID,
                                           String operateType) {
        throw new UnsupportedOperationException("not implement this method, use CodeManager.");
    }

    private final static String GET_POST_DEPT_LIST =
        "select elements(o.sheetMove) from o in " + SheetProcess.class +
        " where o.flowID=:flowID and o.executeDept=:deptID and o.operationType=:operateType";
    /**
     * getPostDeptList
     *
     * @param flowID String
     * @param deptID String
     * @param operateType String
     * @return List
     */
    public List getPostDeptList(final String flowID, final String deptID,
                                final String operateType) {
        final HibernateTemplate ht = getHibernateTemplate();
        return (List) ht.execute(new HibernateCallback() {
            /**
             * doInHibernate
             *
             * @param session Session
             * @throws HibernateException
             * @return Object
             */
            public Object doInHibernate(Session session) throws HibernateException {
                Query query = session.createQuery(GET_POST_DEPT_LIST);
                query.setString("flowID", flowID);
                query.setString("deptID", deptID);
                query.setString("operateType", operateType);
                List sheetMoves = query.list();

                List postDepts = new ArrayList();
                for (Iterator iter = sheetMoves.iterator(); iter.hasNext(); ) {
                    SheetMove move = (SheetMove) iter.next();
                    if (Constants.TRUE.equals(move.getIncludeChildren())) {
                        move.setSubDepts(HibernateUserSupportHelper.getInstance().getDepartmentTreeList(
                            session, ht, move.getDistDept(), Department.TYPE_THR));
                    }
                    postDepts.add(move);
                }

                return postDepts;
            }

        });
    }

    /**
     * getNextDeptID
     *
     * @param flowID String
     * @param deptID String
     * @param operateType String
     * @return String
     */
    public String getNextDeptID(final String flowID, final String deptID,
                                final String operateType) {
        HibernateTemplate ht = getHibernateTemplate();
        return (String) ht.execute(new HibernateCallback() {
            /**
             * doInHibernate
             *
             * @param session Session
             * @throws HibernateException
             * @return Object
             */
            public Object doInHibernate(Session session) throws HibernateException {
                Query query = session.createQuery(GET_POST_DEPT_LIST);
                query.setString("flowID", flowID);
                query.setString("deptID", deptID);
                query.setString("operateType", operateType);
                List sheetMoves = query.list();
                if (!sheetMoves.isEmpty())
                    return ((SheetMove)sheetMoves.get(0)).getDistDept();
                else
                    return null;
            }

        });
    }

    private final static String GET_FUNC_OPERATION_LIST =
            "from o in " + SheetOperation.class +
            " where o.flowID=:flowID and o.executeDept in ('00', :deptID) and o.functionType=:funcType and o.statusType in ('00', :statusType)" +
            " order by o.orderIndex";
    /**
     * getFuncOperationList
     *
     * @param flowID String
     * @param deptID String
     * @param funcType String
     * @param statusType String
     * @return List
     */
    public List getFuncOperationList(final String flowID, final String deptID,
                                     final String funcType, final String statusType) {
        HibernateTemplate ht = getHibernateTemplate();
        return (List) ht.execute(new HibernateCallback() {
            /**
             * doInHibernate
             *
             * @param session Session
             * @throws HibernateException
             * @return Object
             */
            public Object doInHibernate(Session session) throws HibernateException {
                Query query = getHibernateTemplate().createQuery(session, GET_FUNC_OPERATION_LIST);
                query.setString("flowID", flowID);
                query.setString("deptID", deptID);
                query.setString("funcType", funcType);
                query.setString("statusType", statusType);
                return query.list();
            }

        });

    }

    private final static String GET_PROCESS_ACTION_LIST =
        "from o in " + SheetAction.class +
        " where o.process.flowID=? and o.process.executeDept='00' and o.process.operationType=?" +
        " order by o.orderIndex";

    private final static String GET_SPEC_PROCESS_ACTION_LIST =
        "from o in " + SheetAction.class +
        " where o.process.flowID=? and o.process.executeDept=? and o.process.operationType=?" +
        " order by o.orderIndex";

    /**
     * getProcessActionList
     *
     * @param flowID String
     * @param deptID String
     * @param operateType String
     * @throws DataAccessException
     * @return List
     */
    public List getProcessActionList(String flowID, String deptID,
                                     String operateType) throws
        DataAccessException {
      HibernateTemplate ht = getHibernateTemplate();
      List psActions = ht.find(GET_SPEC_PROCESS_ACTION_LIST, new Object[] {flowID,
                               deptID, operateType}
                               ,
                               new Type[] {Hibernate.STRING, Hibernate.STRING,
                               Hibernate.STRING, });
      if (psActions.size() > 0) {
        return psActions;
      }
      else
        return ht.find(GET_PROCESS_ACTION_LIST,
                       new Object[] {flowID, operateType, }
                       ,
                       new Type[] {Hibernate.STRING, Hibernate.STRING, });
    }


    /**
     * doOperate
     *
     * @param authToken AuthToken
     * @param flowID String
     * @param deptID String
     * @param operateType String
     * @param doCtx DoOperateContext
     * @return DoOperateContext
     */
    public DoOperateContext doOperate(AuthToken authToken, String flowID, String deptID,
                                      String operateType, DoOperateContext doCtx) {
        throw new UnsupportedOperationException("not implement this method, use proxy.");
    }

    /**
     * getDeptChildrenAsMove
     *
     * @param deptID String
     * @return List
     */
    public List getDeptChildrenAsMove(final String deptID) {
        return (List) getHibernateTemplate().execute(new HibernateCallback() {
            /**
             * doInHibernate
             *
             * @param session Session
             * @return Object
             * @throws HibernateException
             */
            public Object doInHibernate(Session session) throws HibernateException {
                List result = new ArrayList();
                List deptList = HibernateUserSupportHelper.getInstance().getDeptChildren(
                    session, getHibernateTemplate(), deptID, Department.TYPE_THR);
                int i = 0;
                for (Iterator iter = deptList.iterator(); iter.hasNext(); i++) {
                    DepartmentTreeViewObject dtvo = (DepartmentTreeViewObject) iter.next();
                    SheetMove sm = new SheetMove();
                    List children = HibernateUserSupportHelper.getInstance().
                        getDepartmentTreeList(session, getHibernateTemplate(),
                                              dtvo.getDepartmentID(),
                                              Department.TYPE_THR);
                    sm.setDistDept(dtvo.getDepartmentID());
                    sm.setOrderIndex(buildIndex(i));
                    sm.setSubDepts(children);
                    if (children != null && !children.isEmpty())
                        sm.setIncludeChildren(Constants.TRUE);
                    else
                        sm.setIncludeChildren(Constants.FALSE);

                    result.add(sm);
                }
                return result;
            }

            private String buildIndex(int i) {
                String idx = "" + (100 + i);
                return idx.substring(1, idx.length());
            }

        });

    }


    /**
     * getDeptChildrenAsMove
     *
     * @param deptID String
     * @param isAll boolean
     * @return List
     */
    public List getDeptChildrenAsMove(final String deptID,final boolean isAll) {
        return (List) getHibernateTemplate().execute(new HibernateCallback() {
            /**
             * doInHibernate
             *
             * @param session Session
             * @return Object
             * @throws HibernateException
             */
            public Object doInHibernate(Session session) throws HibernateException {
                List result = new ArrayList();
                List deptList = new ArrayList();
                if(isAll==true)
                  deptList = HibernateUserSupportHelper.getInstance().getDeptChildren(
                    session, getHibernateTemplate(), deptID);
                else if(isAll==false)
                  deptList = HibernateUserSupportHelper.getInstance().getDeptChildren(
                    session, getHibernateTemplate(), deptID, Department.TYPE_THR);
                int i = 0;
                for (Iterator iter = deptList.iterator(); iter.hasNext(); i++) {
                    DepartmentTreeViewObject dtvo = (DepartmentTreeViewObject) iter.next();
                    SheetMove sm = new SheetMove();
                    List children = new ArrayList();
                    if(isAll==true)
                      children = HibernateUserSupportHelper.getInstance().
                        getDepartmentTreeList(session, getHibernateTemplate(),
                                              dtvo.getDepartmentID());
                    else if(isAll==false)
                      children = HibernateUserSupportHelper.getInstance().
                          getDepartmentTreeList(session, getHibernateTemplate(),
                        dtvo.getDepartmentID(),
                        Department.TYPE_THR);
                    sm.setDistDept(dtvo.getDepartmentID());
                    sm.setOrderIndex(buildIndex(i));
                    sm.setSubDepts(children);
                    if (children != null && !children.isEmpty())
                        sm.setIncludeChildren(Constants.TRUE);
                    else
                        sm.setIncludeChildren(Constants.FALSE);

                    result.add(sm);
                }
                return result;
            }

            private String buildIndex(int i) {
                String idx = "" + (100 + i);
                return idx.substring(1, idx.length());
            }

        });

    }


    public Department retrieveDepartment(String deptID){
        HibernateTemplate ht = getHibernateTemplate();
        return (Department)ht.load(Department.class,deptID);
    }

    public List getLeafDeptAsMove(String deptID,String flowID) {
        List result = new ArrayList();
        SheetMove sm = new SheetMove();
        sm.setDistDept(deptID);
        sm.setFlowID(flowID);
        sm.setSubDepts(new ArrayList());
        sm.setIncludeChildren(Constants.FALSE);
        result.add(sm);
        return result;
    }
    public void  updateTime(String dealTime,String sendTime)
    {
    	
    	
    	 HibernateTemplate ht = getHibernateTemplate();
    	 
    	 TimeLimit timeLimit=new TimeLimit();
    	 timeLimit.setTimeId("TD");
    	 timeLimit.setDealTime(dealTime);
    	 timeLimit.setSendTime(sendTime);
    	 
    	 ht.saveOrUpdate(timeLimit);
    	 
    	 
    	 
    }

	public TimeLimit getTimeLimit() {
		// TODO Auto-generated method stub
		 HibernateTemplate ht = getHibernateTemplate();
		 TimeLimit timeLimit=(TimeLimit)ht.get(TimeLimit.class, "TD");
		 
		 return timeLimit;
	}
    
    

}
